#pragma once 
#include <vector>
#include <string>
//#include "ASTNode.h"

using std::vector;
using namespace std;

class ASTNode;
class ParentLink;
class ChildLink;
class SiblingLink;

class AST
{
	public:

		ASTNode* rootNode;
		vector<ASTNode*> nodes;

		vector<ParentLink*> parentTable;
		vector<SiblingLink*> siblingTable;
		vector<ChildLink*> childTable;

		AST(void);
		vector<ASTNode*> addNode(ASTNode* node);
		
		//void insertLink(ASTLink* nodeLink);
		void setParentLink(ASTNode* fromNode, ASTNode* toNode);
		void setSiblingLink(ASTNode* fromNode, ASTNode* toNode);
		void setChildLink(ASTNode* fromNode, ASTNode* toNode, unsigned int childNumber);

		//Not done yet
		ASTNode* getRootNode();
		ASTNode* getParentNode(ASTNode* fromNode);
		ASTNode* getSiblingNode(ASTNode* fromNode);
		ASTNode* getChildNode(ASTNode* fromNode, unsigned int childNumber);
		vector<ASTNode*>getRevParentNode(ASTNode* toNode);
		ASTNode* getRevSiblingNode(ASTNode* toNode);
		ASTNode* getRevChildNode(ASTNode* toNode);
		ASTNode* getNode(unsigned int lineNumber);

		//New API
		ASTNode* getNodeByIndex(unsigned int nodeIndex);

		//Query
		unsigned int getFollow(unsigned int targetStatement);
		unsigned int getFollowBy(unsigned int targetStatement);
		vector<unsigned int> getFollowTC(unsigned int targetStatement);
		vector<unsigned int> getFollowTCBy(unsigned int targetStatement);
		bool isFollow(unsigned int targetStatement_1, unsigned int targetStatement_2); 
		bool isFollowTC(unsigned int targetStatement_1, unsigned int targetStatement_2);

		unsigned int getParent(unsigned int targetStatement);
		vector<unsigned int> getParentBy(unsigned int targetStatement);
		vector<unsigned int> getParentTC(unsigned int targetStatement);
		vector<unsigned int> getParentByTC(unsigned int targetStatement);
		bool isParent(unsigned int targetStatement_1, unsigned int targetStatement_2);
		bool isParentTC(unsigned int targetStatement_1, unsigned int targetStatement_2);

		//void printTable(void);

	private:
		static const unsigned int ROOT_INDEX = 0;

		//Helper functions for recursive operation
		unsigned int _getFollowTC(unsigned int targetStatement);
		unsigned int _getFollowTCBy(unsigned int targetStatement);
		
		//ASTLinksTable* linkTable;
};